Skip to content

Add prefer-import-meta-properties rule #2607

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 38 commits into from
Mar 31, 2025

Conversation

ota-meshi
Copy link
Contributor

@ota-meshi ota-meshi commented Mar 26, 2025

This PR adds prefer-import-meta-properties rule that reports the following code:

import path from "path";
import { fileURLToPath } from "url";
const dirname1 = path.dirname(fileURLToPath(import.meta.url));
const dirname2 = path.dirname(import.meta.filename);
const dirname3 = fileURLToPath(new URL(".", import.meta.url));
const filename1 = fileURLToPath(import.meta.url);
const filename2 = fileURLToPath(new URL(import.meta.url));

close #2255

@ota-meshi
Copy link
Contributor Author

I realized that new URL(".", import.meta.url).pathname shouldn't be reported because it can be used in the browser.
I'll change this PR.

@ota-meshi
Copy link
Contributor Author

I have changed this PR.

@fisker
Copy link
Collaborator

fisker commented Mar 26, 2025

I realized that new URL(".", import.meta.url).pathname shouldn't be reported because it can be used in the browser. I'll change this PR.

new URL("./", import.meta.url).pathname should use the same logic.

@ota-meshi
Copy link
Contributor Author

Thank you!
I changed it to check new URL("./", ...) as well.

const fix = fixer =>
fixer.replaceText(node, `import.meta.${name}`);

if (filename.endsWith('.mjs')) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should import.meta already ensure these files are in ESM? Why this check needed?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we give the community some time to drop Node.js 18, and add an option instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you're right, no need to check for mjs 😓
It's definitely an ESM because it already uses import.meta.
I'll change that.

Copy link
Contributor Author

@ota-meshi ota-meshi Mar 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we give the community some time to drop Node.js 18, and add an option instead?

With Node v18 reaching EOL next month, I'm not sure if it should be an option 😅

#2255 (comment)

@ota-meshi
Copy link
Contributor Author

Thank you for your review!
I have made some changes to this PR.

Copy link
Collaborator

@fisker fisker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ota-meshi Please take a look

@ota-meshi
Copy link
Contributor Author

Thank you for reviewing this PR!
I've made some changes to this PR, could you please check it again?

@fisker
Copy link
Collaborator

fisker commented Mar 29, 2025

Pushed some commits, most of them are making all kinds of check stricter and improve readability.

@fisker
Copy link
Collaborator

fisker commented Mar 29, 2025

Due to bug in iterateProblemsFromFilename, I found a broken case 7816928 , can you fix?

@ota-meshi
Copy link
Contributor Author

I think it's the same test case as L406, and I think it's intentional. Any suggestions on how to fix it 🤔

@fisker
Copy link
Collaborator

fisker commented Mar 29, 2025

I think it's the same test case as L406, and I think it's intentional. Any suggestions on how to fix it 🤔

Sorry, I was wrong about it.

@fisker
Copy link
Collaborator

fisker commented Mar 29, 2025

Everything looks good to me, except one thing.

Do you think it's possible that we break this case?

const x = new URL(import.meta.url).pathname
const filename = isWindows() ? x.slice(1) :x

Since new URL('file:///C:/file').pathname is actually /C:/file, not C:/file

@fisker
Copy link
Collaborator

fisker commented Mar 29, 2025

Also, about this

Should we give the community some time to drop Node.js 18, and add an option instead?

Your answer make sense to me

With Node v18 reaching EOL next month, I'm not sure if it should be an option 😅

But I don't want people to disable this rule only because their target environment doesn't have import.meta.{dirname,filename}.

Personally, I even prefer add this PR as a separate rule, this part also not technically "prefer-module".

import.meta maybe also keep adding new stuff, having a separate rule should be easier to maintain.

@sindresorhus What do you think?

@ota-meshi
Copy link
Contributor Author

Since new URL('file:///C:/file').pathname is actually /C:/file, not C:/file

Thank you for your comment, I didn't know it would return different results for Windows paths 😅
I will change it to not report .pathname.

@ota-meshi
Copy link
Contributor Author

Personally, I even prefer add this PR as a separate rule, this part also not technically "prefer-module".

By the way, originally I wanted a rule to be added to convert path.dirname(fileURLToPath(import.meta.url)) to import.meta.dirname. I searched for similar issues in this repository and found #2255, so I implemented it in prefer-module and opened a PR.
It's useful for me either in the prefer-module rule or in another rule 😄

@sindresorhus
Copy link
Owner

It could be a separate rule, but isn't it easier just to keep it in here under an option? We still want this rule to enforce not using __dirname, and we want a fix-it for that, and that fix it should ideally be import.meta.dirname (when an option is enabled). So while a different rule could handle the fileURLToPath(import.meta.url) and path.dirname(import.meta.filename) case. It just seems easier to have it all here.

@fisker
Copy link
Collaborator

fisker commented Mar 31, 2025

__dirname

We already provide both
import.meta.dirname and path.dirname(url.fileURLToPath(import.meta.url)) as suggestion.

If the new rule enabled, it doesn't matter which one user choose, user will end up using import.meta.dirname.

Since you are not against seperate rule, let's do it.

My suggestion for rule name is prefer-import-meta-properties.

@ota-meshi
Copy link
Contributor Author

My suggestion for rule name is prefer-import-meta-properties.

👍

I will change this PR to add the new rule.

@ota-meshi ota-meshi changed the title prefer-module: Support import.meta.{dirname,filename} Add prefer-import-meta-properties rule Mar 31, 2025
Copy link
Collaborator

@fisker fisker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job! Thank you!

@sindresorhus sindresorhus merged commit 1f6e172 into sindresorhus:main Mar 31, 2025
17 checks passed
@ota-meshi ota-meshi deleted the prefer-module-import-meta branch March 31, 2025 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support import.meta.dirname and import.meta.filename in prefer-module rule
3 participants